import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { PKRequestConfig } from './type'
import { localCache } from '@/utils/cache'
import { USERINFO } from '@/global/contants'

// 拦截器: 蒙版 loading ... / token / 修改配置

class PKRequest {
  instance: AxiosInstance
  // request实例 => axios实例
  constructor(config: PKRequestConfig) {
    this.instance = axios.create(config)
    // 全局拦截器：给每个instance实例都添加拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // loading token
        if (localCache.getCache(USERINFO)) {
          const userInfo = localCache.getCache(USERINFO)
          config.headers.token = userInfo.token
        }
        console.log('全局请求成功的拦截器')
        return config
      },
      (err) => {
        console.log('全局请求失败的拦截器')
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        // loading token
        console.log('全局响应成功的拦截器')
        return res
      },
      (err) => {
        console.log('全局响应失败的拦截器')
        return err
      }
    )

    // 判断是否携带拦截器

    this.instance.interceptors.request.use(
      config.interceptors?.requestOnFulfilledFn as any,
      config.interceptors?.requestOnRejectedFn
    )
    this.instance.interceptors.response.use(
      config.interceptors?.responseOnFulfilledFn,
      config.interceptors?.responseOnRejectedFn
    )
  }

  // 封装网络请求的方法
  request<T = any>(config: PKRequestConfig<T>) {
    // 单次请求的成功拦截处理
    if (config.interceptors?.requestOnFulfilledFn) {
      config = config.interceptors.requestOnFulfilledFn(config)
    }
    // 返回的promise
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 单次响应的成功拦截处理
          if (config.interceptors?.responseOnFulfilledFn) {
            res = config.interceptors.responseOnFulfilledFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }
  get<T = any>(config: PKRequestConfig<T>) {
    return this.instance.request<any, T>({ method: 'GET', ...config })
  }
  post<T = any>(config: PKRequestConfig<T>) {
    return this.instance.request<any, T>({ method: 'POST', ...config })
  }
  put<T = any>(config: PKRequestConfig<T>) {
    return this.instance.request<any, T>({ method: 'PUT', ...config })
  }
  delete<T = any>(config: PKRequestConfig<T>) {
    return this.instance.request<any, T>({ method: 'DELETE', ...config })
  }
  patch<T = any>(config: PKRequestConfig<T>) {
    return this.instance.request<any, T>({ method: 'PATCH', ...config })
  }
}
export default PKRequest
